#ifndef AVHANDLER_H
#define AVHANDLER_H

#include <QtGui/QImageIOHandler>

extern "C" {
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libavdevice/avdevice.h"
}
class AVHandler : public QImageIOHandler
{
public:
    AVHandler();
    ~AVHandler();
    bool canRead() const;
    bool read(QImage *image);
    void setFileName(const QString &fileName);
    //void setOption(ImageOption option, const QVariant &value); // Not yet implemented
    QVariant option(ImageOption option) const;
    bool supportsOption(ImageOption option) const;
    int currentImageNumber() const {
        return codecContext->frame_number;
    }
    //bool jumpToNextImage();  // Not yet implemented
    //bool jumpToImage(int imageNumber);  // Not yet implemented
    int loopCount() const {
        return 1;
    }
    int nextImageDelay() const;
    int imageCount() const {
        return stream->nb_frames;
    }
    //QRect currentImageRect() const;  // Not yet implemented

private:
    static int readFn(void *opaque, quint8 *buf, int buf_size);
    static qint64 seekFn(void *opaque, qint64 offset, int whence);

    static quint32 fromYuv(qint16 y, qint16 u, qint16 v);
    static void yuv420_rgb(AVFrame *frame, char *buffer, const QRect &roi);
    static void yuv422_rgb(AVFrame *frame, char *buffer, const QRect &roi);
    static void bgr24_rgb(AVFrame *frame, char *buffer, const QRect &roi);

    mutable bool isReadable;
    mutable int pos;
    mutable AVFormatContext *formatContext;
    mutable AVCodec *codec;
    mutable AVStream *stream;
    mutable AVCodecContext *codecContext;
    mutable AVDictionary *options;
    AVIOContext *ioContext;
    AVFrame *frame;

    QString m_fileName;
};

#endif // AVHANDLER_H
